/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.editpart;

import java.util.Iterator;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.editpolicies.NonResizableEditPolicy;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ElementImport;
import org.eclipse.uml2.uml.NamedElement;

import com.cea.papyrus.core.directedit.LabelDirectEditPolicy;
import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.figures.StringFigure;
import com.cea.papyrus.core.utils.Debug;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;


/**
 * Editpart used to display the name of a node.
 */
public class NodeNameDisplayEditPart extends GraphNodeWithSemanticEditPart implements IUMLElementEditPart {

	/**
	 * The element type accepted by the associated list model.
	 * If <code>null</code>, any type is accepted.
	 */
	protected org.eclipse.uml2.uml.Element element;

	/** Debug channel */
	protected final int channel=14;

//	/** Manager for editing class name */
//	protected DirectEditManager manager;
//
//	/** direct edition mode */
//	protected int directEditionMode = IDirectEdition.UNDEFINED_DIRECT_EDITOR;
//
//	private IDirectEditorConfiguration configuration;

	/**
	 * Create a FeatureList EditPart accepting any kind from drag and drop.
	 * @param modelManager 
	 * @param graphnode 
	 */

	public NodeNameDisplayEditPart(GraphNode graphnode, ModelManager modelManager) {
		super(graphnode,modelManager);
		Debug.debug(this,"create NameDisplayEditPart()",channel);
		this.element = null;
	}

	/**
	 * Create a FeatureList EditPart accepting specified type from drag and drop.
	 * Create a ListEditPart for a List accepting only specified element.
	 * @param element 
	 * @param modelManager 
	 * @param elementType 	 * @param graphnode 
	 */
	public NodeNameDisplayEditPart(GraphNode graphnode,org.eclipse.uml2.uml.Element element,ModelManager modelManager) {
		super(graphnode,modelManager);
		Debug.debug(this,"create NameDisplayEditPart("+ element+")",channel);
		this.element = element;
	}

	/**
	 * 
	 */
	@Override
	protected void createEditPolicies(){
		installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new LabelDirectEditPolicy());
		installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, new NonResizableEditPolicy());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void activate() {
		if (this.getGraphNode().getSemanticParent()!=null){
			((Notifier)this.getGraphNode().getSemanticParent()).eAdapters().add(graphElementListener);
			Iterator propertiesIterator= this.getGraphNode().getSemanticParent().getProperty().iterator();
			while(propertiesIterator.hasNext()){
				((Notifier)propertiesIterator.next()).eAdapters().add(graphElementListener);
			}
		}
		super.activate();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void deactivate() {
		if (this.getGraphNode().getSemanticParent()!=null){
			((Notifier)this.getGraphNode().getSemanticParent()).eAdapters().remove(graphElementListener);
			Iterator propertiesIterator= this.getGraphNode().getSemanticParent().getProperty().iterator();
			while(propertiesIterator.hasNext()){
				((Notifier)propertiesIterator.next()).eAdapters().remove(graphElementListener);
			}
		}
		// stop listening for changes in the model
		super.deactivate();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected IFigure createFigure() {
		if(element instanceof NamedElement){
			return new StringFigure(((NamedElement)element).getName());} 
		else {
			return new StringFigure("");
		}
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	protected Label getNameLabel() {
		return (StringFigure)getFigure();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public  Element getUmlElement(){
		return element;
	} 

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean isElementImport(){
		return (element instanceof ElementImport);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public ElementImport getElementImport(){
		if (element instanceof ElementImport){
			return (ElementImport)element;
		}
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void refreshVisuals() {
		Dimension size = getFigure().getPreferredSize();
		Point p = getGraphNode().getPosition();
		Rectangle r = new Rectangle(p ,size);
		StringFigure f = (StringFigure)getFigure();
		if(element instanceof NamedElement){
			f.setText(((NamedElement)element).getName());}
		f.setVisible(this.isVisible());

		((GraphicalEditPart) getParent()).setLayoutConstraint(
				this,
				f,
				r);
	}

//	/**
//	 * Init the label direct edit manager.
//	 * This method should be called when a Direct Edit request is performed.
//	 */
//	protected void initLabelEditManager() {
//		if(manager==null) {
//			// locator for the cell editor (on the name label)
//			CellEditorLocator locator = new SimpleCellEditorLocator(getFigure());
//
//			// defining how properties are modified in the model
//			PropertyAccessor accessor = new PropertyAccessor() {
//				public String getPropertyName() {
//					return "Name";
//				}
//
//				public String getValue() {
//					if(element instanceof NamedElement) {
//						return ((NamedElement)element).getName();
//					}
//					return "";
//				}
//				public void setValue(String value) {
//					if(element instanceof NamedElement) {
//						((NamedElement)element).setName(value);
//					}  
//				}
//			};
//			// defines the controler: link between model and view
//			ILabelControler labelControler = new FigureControler(getFigure(), accessor);
//
//			// creates the editing manager.
//			manager = new LabelDirectEditManager(this, locator, labelControler);
//		}
//	}
//
//	/**
//	 * the direct edit mechanism requires the edit part to handle the direct edit
//	 * request.
//	 * @param req the request that called the direct edit.
//	 */
//	public void performDirectEdit(Request req) {
//		if(IDirectEdition.UNDEFINED_DIRECT_EDITOR == directEditionMode) {
//			directEditionMode = getDirectEditionType();
//		}
//		switch(directEditionMode) {
//		case IDirectEdition.EXTENDED_DIRECT_EDITOR:
//			// opens a dialog using specific configuration
//			configuration.preEditAction(getUmlElement());
//			final ExtendedDirectEditionDialog dialog = new ExtendedDirectEditionDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
//					getUmlElement(),
//					configuration.getTextToEdit(getUmlElement()),
//					configuration);
//			if(Window.OK==dialog.open()) {
//				// apply modifications
//				final AdapterFactoryEditingDomain emfDomain = getModelManager().getDiResourceSet().getEditingDomain();
//				EMFtoGEFWrapCommand command = new EMFtoGEFWrapCommand(emfDomain) {
//					@Override
//					public Command createEMFCommand() {
//						return new ChangeCommand(emfDomain, new Runnable() {
//							public void run() {configuration.postEditAction(getUmlElement(), dialog.getValue());};
//						}, "Edit Label", "Edit the label of the selected element");
//					}
//				};
//				EditDomain gefDomain = getRoot().getViewer().getEditDomain();
//				gefDomain.getCommandStack().execute(command);
//			}
//
//			break;
//		case IDirectEdition.DEFAULT_DIRECT_EDITOR:
//			// initialize the direct edit manager 
//			initLabelEditManager();
//			manager.show();
//			break;
//		default: 
//			break;
//		}
//
//	}
//
//	/**
//	 * Returns the style of direct edition
//	 * @return the style of direct edition
//	 */
//	protected int getDirectEditionType() {
//		if(DirectEditorsUtil.hasSpecificEditorConfiguration(IDirectEditorsIds.UML_LANGUAGE, getUmlElement().eClass().getInstanceClassName())) {
//			if(configuration == null) {
//				configuration = DirectEditorsUtil.findEditorConfiguration(IDirectEditorsIds.UML_LANGUAGE, getUmlElement().eClass().getInstanceClassName());
//				// a specific editor has been found
//			}
//			return IDirectEdition.EXTENDED_DIRECT_EDITOR;
//		}
//		return IDirectEdition.DEFAULT_DIRECT_EDITOR;
//	}
//
//	/**
//	 * {@inheritDoc}
//	 */
//	@Override
//	public void performRequest(Request request){
//		if (RequestConstants.REQ_DIRECT_EDIT.equals(request.getType())) {
//			performDirectEdit(request);
//		}
//	}

	/**
	 * Return false.
	 * This method is used in {@link com.cea.papyrus.core.editpart.LayoutEditPolicy} in order to
	 * know how to compute the coordinate of a added part.
	 * TODO move this method to more appropriate place. 
	 * @return
	 */
	@Override
	public boolean needRelativeTranslationForAddCommand() {
		return false;
	}
}
